package org.changs.control.ui.carupdate;

import com.androidnetworking.AndroidNetworking;
import com.androidnetworking.error.ANError;
import com.androidnetworking.interfaces.DownloadListener;
import com.google.gson.JsonObject;

import org.changs.aplug.base.BasePresenter;
import org.changs.aplug.utils.EmptyUtils;
import org.changs.common.network.ApiHelper;
import org.changs.common.network.model.CarVersion;
import org.changs.servlet.AplugClient;
import org.changs.servlet.CommunicationConfig;
import org.changs.servlet.IOUtils;
import org.changs.servlet.SenderFileCallback;

import java.io.File;

import javax.inject.Inject;
import javax.inject.Singleton;

import aplug.AppManager;
import aplug.data.prefs.PreferencesHelper;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;

/**
 * Created by 惠安 on 2017/12/20.
 */

@Singleton
public class CarUpdatePresenter extends BasePresenter<CarUpdateContract.V> implements CarUpdateContract.P {

    public static final int STATE_DEFAULT = 0;
    public static final int STATE_CHECKING = 1;
    public static final int STATE_NEWEST = 2;
    public static final int STATE_CAN_UPGRADE = 3;
    public static final int STATE_DOWNING = 4;//正在下载
    public static final int STATE_CAN_2VEHICLE = 5;//可传输到车机
    public static final int STATE_2VEHICLEING = 6;

    private final ApiHelper mApiHelper;
    private final PreferencesHelper mPreferencesHelper;
    private final AppManager mAppManager;

    private File mOtaFile;
    private int mState = STATE_DEFAULT;
    private CarVersion mNewCarVersion;

    @Inject
    public CarUpdatePresenter(ApiHelper apiHelper, PreferencesHelper preferencesHelper, AppManager appManager) {
        this.mApiHelper = apiHelper;
        this.mPreferencesHelper = preferencesHelper;
        this.mAppManager = appManager;

        init();
    }

    @Override
    public void updateState() {
        updateState(null);
    }

    @Override
    public void updateState(String des) {
        if (isDetachView()) return;
        switch (mState) {
            case STATE_DEFAULT:
                getMvpView().carVersionDefault();
                break;
            case STATE_CHECKING:
                getMvpView().carVersionChecking();
                break;
            case STATE_NEWEST:
                getMvpView().carVersionNewest();
                break;
            case STATE_CAN_UPGRADE:
                getMvpView().carVersionCanUpdate(mNewCarVersion);
                break;
            case STATE_DOWNING:
                getMvpView().carVersionDownloading(0);
                break;
            case STATE_CAN_2VEHICLE:
                getMvpView().carOtaCan2Vehicle();
                break;
        }
    }

    private void init() {
        String upgradeFilePath = mPreferencesHelper.getCarVersionWait2Vehicle();
        if (upgradeFilePath != null) {
            File file = new File(upgradeFilePath);
            if (!file.exists()) {
                mPreferencesHelper.setCarVersionWait2Vehicle(null);
            } else {
                mOtaFile = file;
                mState = STATE_CAN_2VEHICLE;
            }
        }
    }

    @Override
    public void checkCarUpgrade() {
        if (mState == STATE_CHECKING) return;
        mState = STATE_CHECKING;
        mApiHelper.checkCarUpgrade()
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(carVersionApiRes -> {
                    if (carVersionApiRes.getCode() != 0) {
                        mState = STATE_DEFAULT;
                        updateState(carVersionApiRes.getMessage());
                        return;
                    }
                    if (carVersionApiRes.getData() == null) {
                        mState = STATE_NEWEST;
                        updateState();
                        return;
                    }
                    mNewCarVersion = carVersionApiRes.getData();
                    if (mNewCarVersion.getCarVersionCode().compareTo(mPreferencesHelper.getCarVersion()) > 0) {
                        mState = STATE_CAN_UPGRADE;
                    } else {
                        mState = STATE_NEWEST;
                    }
                    updateState();
                }, throwable -> {
                    mState = STATE_DEFAULT;
                    updateState();
                });
    }

    @Override
    public void download() {
        if (mNewCarVersion == null || mNewCarVersion.getUrl() == null) return;
        if (mState == STATE_DOWNING) return;
        mState = STATE_DOWNING;
        updateState();
        AndroidNetworking.download(mNewCarVersion.getUrl(),
                "/sdcard/car_control", String.format("t3_p3-ota-%s.zip", mNewCarVersion.getCarVersionCode()))
                .build()
                .setDownloadProgressListener((bytesDownloaded, totalBytes) -> {
                    if (isAttachView())
                        getMvpView().carVersionDownloading(bytesDownloaded / (float)totalBytes);
                })
                .startDownload(new DownloadListener() {
                    @Override
                    public void onDownloadComplete() {
                        if (isAttachView()) getMvpView().carVersionDownloading(100);
                        String path = String.format("/sdcard/car_control/t3_p3-ota-%s.zip", mNewCarVersion.getCarVersionCode());
                        mPreferencesHelper.setCarVersionWait2Vehicle(path);
                        mOtaFile = new File(path);
                        mState = STATE_CAN_2VEHICLE;
                        updateState();
                    }

                    @Override
                    public void onError(ANError anError) {
                        mState = STATE_CAN_UPGRADE;
                        updateState();
                    }
                });
    }

    @Override
    public void ota2Vehicle() {
        String remoteIp = mAppManager.getRemoteIp();
        if (mOtaFile == null || EmptyUtils.isEmpty(remoteIp)) {
            return;
        }
        if (mState == STATE_2VEHICLEING) return;
        mState = STATE_2VEHICLEING;
        JsonObject message = new JsonObject();
        message.addProperty(IOUtils.EXTRA_FILE_TYPE, "ota");


        Observable
                .fromCallable(() -> {
                    AplugClient.send(remoteIp, CommunicationConfig.S3_SERVER_PORT, message, mOtaFile, new MySenderFileCallback());
                    return true;
                })
                .subscribeOn(Schedulers.io())
                .subscribe();
    }

    private class MySenderFileCallback implements SenderFileCallback {
        @Override
        public void onNext(int code, String msg) {

        }

        @Override
        public void onProgress(int progress) {

        }

        @Override
        public void onError(int code, String msg) {
            Observable.empty()
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(o -> Timber.d("传输失败！"));
        }

        @Override
        public void onSuccess() {
            Observable.empty()
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(o -> {
                        String name = mOtaFile.getName();
                        int end = name.lastIndexOf(".");
                        String version = name.substring(10, end);
                        mPreferencesHelper.setCarVersion(version);
                        mPreferencesHelper.setCarVersionWait2Vehicle(null);
                        mState = STATE_NEWEST;
                        updateState();
                    });
        }

        @Override
        public void onComplete() {

        }
    }
}
